package win.demonlegion.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.userdetails.UserDetails;
import win.demonlegion.module.SysUserBean;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by john on 2017/7/18.
 */
public class JwtTokenUtil {
    private static final Logger logger = LoggerFactory.getLogger(JwtTokenUtil.class);

    public static String getUsernameFromToken(String token) {
        Claims claims = getClaimsFromToken(token);
        if(claims != null) {
            return claims.getSubject();
        }
        return null;
    }

    public static String getUsernameFromUserId(String token) {
        Claims claims = getClaimsFromToken(token);
        if(claims != null) {
            return claims.getAudience();
        }
        return null;
    }

    public static boolean validateToken(String token, UserDetails userDetails) {
        Claims claims = getClaimsFromToken(token);
        if(claims != null) {
            Calendar calendar = Calendar.getInstance();
            Date date = calendar.getTime();
            if (claims.getSubject().equals(userDetails.getUsername()) && claims.getAudience().equals(userDetails.getPassword())
                    && claims.getIssuer().equals("corefac") && date.before(claims.getExpiration())) {
                return true;
            }
        }
        return false;
    }

    public static String getUserToken(SysUserBean sysUserBean) {
        if(sysUserBean != null) {
            Map<String, Object> claims = new HashMap<>();
            claims.put("sub", sysUserBean.getUsername());
            claims.put("aud", sysUserBean.getId());
            claims.put("iss", "corefac");
            claims.put("authories", StringUtils.join(sysUserBean.getTokenAuthorities(), ","));

            return generateToken(claims);
        }
        return null;
    }

    private static String generateToken(Map<String, Object> claims) {
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(generateExpirationDate())
                .signWith(SignatureAlgorithm.HS512, "test") //采用什么算法是可以自己选择的，不一定非要采用HS512
                .compact();
    }

    private static Date generateExpirationDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, 1);
        return calendar.getTime();
    }

    private static Claims getClaimsFromToken(String token) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey("test")
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            claims = null;
        }
        return claims;
    }
}
